#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <queue>
#include <stack>

using namespace std;
typedef __int64 LONG; 

struct Node
{
	Node(int price)
	{
		Price = price;
		Pick = true;
		MinPrice = price;
	}

	int Price;
	bool Pick;
	int MinPrice;
};

int P;
vector<int>						Teams;
vector<vector<Node> > Tickets;

#define TEAM_COUNT (1<<P)
#define MATCH_COUNT ((1<<P)-1)
#define MATCH_COUNT_IN(lv) (1<<(P-lv-1))

bool IsTeamOk (int teamIdx)
{
	int min = P -Teams[teamIdx];
	if (min<=0)
		return true;

	int picked =0;
	for (int i=0; i<P; i++)
	{
		int idx =teamIdx>>(i+1);
		if (Tickets[i][idx].Pick)
		{
			picked ++;
			if (picked >= min)
				return true;
		}
	}

	return false;
}

bool IsMatch()
{
	for (int i=0; i<TEAM_COUNT; i++)
	{
		if (!IsTeamOk(i))
			return false;
	}

	return true;
}

bool PullDown(int lv,int idx)
{
	Tickets[lv][idx].Pick = true;

	if (lv ==0 
		|| Tickets[lv][idx].Price <= Tickets[lv][idx].MinPrice 
		|| Tickets[lv-1][idx*2].Pick || Tickets[lv-1][idx*2+1].Pick)
	{
		return false;
	}

	Tickets[lv][idx].Pick = false;

	PullDown(lv -1, idx*2);
	PullDown(lv -1, idx*2+1);

	return true;
}

void FindBest()
{
	for (int lv=1; lv<P; lv++)
	{
		for (int i =0; i<MATCH_COUNT_IN(lv); i++)
		{
			int minPrice =Tickets[lv-1][i*2].MinPrice +Tickets[lv-1][i*2+1].MinPrice;

			if (minPrice < Tickets[lv][i].MinPrice)
				Tickets[lv][i].MinPrice = minPrice;
		}
	}

	for (int lv=1; lv<P; lv++)
	{
		bool clear = false;

		if (!clear)
		{
			clear = true;
			for (int i =0; i<MATCH_COUNT_IN(lv); i++)
			{
				if (Tickets[lv][i].Pick)
				{
					if (PullDown(lv,i))
						clear=false;
				}
			}
		}
	}

}

int Solve()
{
	for (int lv=0; lv<P; lv++)
	{
		for (int i =0; i<MATCH_COUNT_IN(lv); i++)
		{
			Tickets[lv][i].Pick = false;

			if (!IsMatch())
				Tickets[lv][i].Pick = true;
		}
	}

	FindBest();

	for (int lv=0; lv<P; lv++)
	{
		for (int i =0; i<MATCH_COUNT_IN(lv); i++)
		{
			Tickets[lv][i].Pick = false;

			if (!IsMatch())
				Tickets[lv][i].Pick = true;
		}
	}

	int r=0;
	for (int lv=0; lv<P; lv++)
	{
		for (int i =0; i<MATCH_COUNT_IN(lv); i++)
		{
			if (Tickets[lv][i].Pick)
				r += Tickets[lv][i].Price;
		}
	}

	return r;
}


void RunCase (ifstream& fin, ofstream& fout)
{
	Teams.clear();
	Tickets.clear();
	
	fin>>P;

	for (int i=0; i<TEAM_COUNT; i++)
	{
		int team;
		fin>>team;
		Teams.push_back(team);
	}

	for (int i=0; i<P; i++)
	{
		vector<Node> lv;

		for (int j=0; j<(1<<(P-1-i)); j++)
		{
			int tkt;
			fin>>tkt;
			lv.push_back(Node(tkt));
		}

		Tickets.push_back(lv);
	}

	int r =Solve();
	fout<<r;
}

void RunAll(const char* fnameIn, const char* fnameOut)
{
	ifstream fin(fnameIn);
	ofstream fout(fnameOut);

	int caseCount;
	fin >> caseCount;

	for (int i=0; i<caseCount; i++)
	{
		fout<<"Case #"<<i+1<<": ";
		RunCase (fin, fout);
		fout<<"\n";
	}
}

void main()
{

	//P =3;
	//
	//Teams.push_back(1);
	//Teams.push_back(2);
	//Teams.push_back(3);
	//Teams.push_back(2);
	//Teams.push_back(1);
	//Teams.push_back(0);
	//Teams.push_back(1);
	//Teams.push_back(3);

	//vector<Node> lv0;
	//lv0.push_back(Node(100));
	//lv0.push_back(Node(150));
	//lv0.push_back(Node(50));
	//lv0.push_back(Node(90));
	//Tickets.push_back (lv0);	

	//vector<Node> lv1;
	//lv1.push_back(Node(500));
	//lv1.push_back(Node(400));
	//Tickets.push_back (lv1);	

	//vector<Node> lv2;
	//lv2.push_back(Node(800));
	//Tickets.push_back (lv2);	

	//int r =Solve();
	
	//RunAll("B-small-practice.in", "B-small-practice.out");
	RunAll("B-large-practice.in", "B-large-practice.out");

	return;
}